REST API ์ค๊ณ ๊ฐ์ด๋: HTTP ๋ฉ์๋์ ์ํ ์ฝ๋ (GET, POST, PUT, PATCH, DELETE)
ํ๋ ์น ์ํคํ ์ฒ์์ **REST(Representational State Transfer)**๋ ๊ฐ์ฅ ๋๋ฆฌ ์ฐ์ด๋ API ์ค๊ณ ๋ฐฉ์์ ๋๋ค. RESTfulํ API๋ฅผ ๋ง๋ ๋ค๋ ๊ฒ์ ๋จ์ํ URL์ ๋ง๋๋ ๊ฒ์ ๋์ด, HTTP ํ์ค ๋ฉ์๋์ ์ํ ์ฝ๋๋ฅผ ๋ชฉ์ ์ ๋ง๊ฒ ์ฌ์ฉํ๋ ๊ฒ์ ์๋ฏธํฉ๋๋ค. 2026๋ ๊ธฐ์ค ์ต์ ์ค๋ฌด ๊ฐ์ด๋๋ฅผ ์ ๋ฆฌํฉ๋๋ค.
1. HTTP ๋ฉ์๋(Verbs)์ ๋ฉฑ๋ฑ์ฑ(Idempotency)
๊ฐ์ฅ ํํ ํ๋ ์ค์๋ ๋ชจ๋ ์์ ์ POST๋ก ์ฒ๋ฆฌํ๊ฑฐ๋, ์์ ์ PUT๊ณผ PATCH๋ฅผ ํผ์ฉํ๋ ๊ฒ์
๋๋ค. ์ด๋ฅผ ๊ตฌ๋ถํ๋ ํต์ฌ ๊ฐ๋
์ **'๋ฉฑ๋ฑ์ฑ'**์
๋๋ค.
๋ฉฑ๋ฑ์ฑ(Idempotency): ๋์ผํ ์์ฒญ์ ์ฌ๋ฌ ๋ฒ ๋ณด๋ด๋ ์๋ฒ์ ์ํ๊ฐ ์ฒ์ ํ ๋ฒ ๋ณด๋์ ๋์ ๊ฐ์ ์ฑ์ง.
| ๋ฉ์๋ | ์ญํ (CRUD) | ๋ฉฑ๋ฑ์ฑ | ์ค๋ช |
|---|---|---|---|
| GET | ์กฐํ (Read) | Yes | ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ฌ ๋ฟ, ์๋ฒ ์ํ๋ฅผ ๋ณ๊ฒฝํ์ง ์์ (Safe) |
| POST | ์์ฑ (Create) | No | ๋ฆฌ์์ค๋ฅผ ์๋ก ๋ง๋ฆ. ์ฌ๋ฌ ๋ฒ ํธ์ถํ๋ฉด ์ฌ๋ฌ ๊ฐ๊ฐ ์๊ธธ ์ ์์ |
| PUT | ๊ต์ฒด (Replace) | Yes | ๋ฆฌ์์ค ์ ์ฒด๋ฅผ ์ ๋ฐ์ดํฐ๋ก ๋ฎ์ด์. ๊ฒฐ๊ณผ๊ฐ ํญ์ ์ผ์ ํจ |
| PATCH | ์์ (Update) | No* | ๋ฆฌ์์ค์ ์ผ๋ถ๋ง ์์ ํจ. (์ผ๋ฐ์ ์ผ๋ก ๋ฉฑ๋ฑํ๊ฒ ์ค๊ณํ๋ ํ์ค์ ์๋) |
| DELETE | ์ญ์ (Delete) | Yes | ๋ฆฌ์์ค๋ฅผ ์ญ์ ํจ. ์ด๋ฏธ ์ญ์ ๋ ๋ฆฌ์์ค์ ๋ ๋ณด๋ด๋ ๊ฒฐ๊ณผ(์ญ์ ๋จ)๋ ๊ฐ์ |
2. ์ค๋ฌด์์ ํท๊ฐ๋ฆฌ๋ PUT vs PATCH
- PUT: "์ด ID์ ๋ฐ์ดํฐ๋ฅผ ๋ด๊ฐ ๋ณด๋ด๋ ๊ฒ์ผ๋ก ํต์งธ๋ก ๋ฐ๊ฟ์ค." ๋ง์ฝ ํน์ ํ๋๋ฅผ ๋๋ฝํ๊ณ ๋ณด๋ด๋ฉด, ๊ทธ ํ๋๋
null์ด ๋๊ฑฐ๋ ๊ธฐ๋ณธ๊ฐ์ผ๋ก ๋ฎ์ด์์์ง ์ํ์ด ์์ต๋๋ค. - PATCH: "์ด ID์ ๋ฐ์ดํฐ ์ค ์ด ํ๋๋ค๋ง ๊ณ ์ณ์ค." ๋ณ๊ฒฝํ๊ณ ์ถ์ ๋ถ๋ถ๋ง ๋ณด๋ด๋ฏ๋ก ๋ฐ์ดํฐ ํจ์จ์ฑ์ด ๋๊ณ ์ค์๋ฅผ ์ค์ผ ์ ์์ต๋๋ค.
3. ์ํฉ๋ณ HTTP ์ํ ์ฝ๋ (Status Codes)
ํด๋ผ์ด์ธํธ๋ ์ํ ์ฝ๋๋ฅผ ๋ณด๊ณ ์์ฒญ์ ์ฑ๊ณต ์ฌ๋ถ๋ฅผ ํ๋จํฉ๋๋ค. ๋จ์ํ 200์ด๋ 500๋ง ์ฐ๋ ๊ฒ์ด ์๋๋ผ, ์๋ฏธ์ ๋ง๋ ์ฝ๋๋ฅผ ๋ฐํํด์ผ ํฉ๋๋ค.
2xx: ์ฑ๊ณต (Success)
- 200 OK: ์กฐํ, ์์ , ์ญ์ ์ฑ๊ณต.
- 201 Created: ์์ฑ(
POST) ์ฑ๊ณต. ํค๋์ ์์ฑ๋ ๋ฆฌ์์ค์ ์์น(Location)๋ฅผ ํฌํจํ๋ ๊ฒ์ด ๊ด๋ก์ ๋๋ค. - 204 No Content: ์ฑ๊ณตํ์ง๋ง ์๋ต ๋ณธ๋ฌธ์ ๋ณด๋ผ ๋ด์ฉ์ด ์์ (์ฃผ๋ก
DELETEํ ์ฌ์ฉ).
4xx: ํด๋ผ์ด์ธํธ ์ค๋ฅ (Client Error)
- 400 Bad Request: ์๋ชป๋ ํ๋ผ๋ฏธํฐ๋ ํ์์ผ๋ก ์์ฒญํ์ ๋.
- 401 Unauthorized: ๋ก๊ทธ์ธ์ด ํ์ํ๋ฐ ํ์ง ์์์ ๋.
- 403 Forbidden: ๋ก๊ทธ์ธ์ ํ์ง๋ง ํด๋น ๋ฆฌ์์ค์ ์ ๊ทผํ ๊ถํ์ด ์์ ๋.
- 404 Not Found: ์กด์ฌํ์ง ์๋ URL์ด๊ฑฐ๋ ๋ฆฌ์์ค์ผ ๋.
- 429 Too Many Requests: ๋๋ฌด ์งง์ ์๊ฐ ๋์ ๋ง์ ์์ฒญ์ ๋ณด๋์ ๋ (Rate Limiting).
5xx: ์๋ฒ ์ค๋ฅ (Server Error)
- 500 Internal Server Error: ์๋ฒ ์ฝ๋ ๋ก์ง ์ค๋ฅ.
- 503 Service Unavailable: ์ ๊ฒ ์ค์ด๊ฑฐ๋ ๊ณผ๋ถํ๋ก ์๋ฒ๊ฐ ์ผ์์ ์ผ๋ก ์ค๋จ๋จ.
4. 2026๋ ๊ธฐ์ค REST API ์ค๊ณ Best Practices
- ๋ช
์ฌํ URI ์ฌ์ฉ:
/getUsers(X) โ/users(O). ํ์๋ HTTP ๋ฉ์๋๋ก ํํํฉ๋๋ค. - ๊ณ์ธต ๊ด๊ณ ํํ:
/users/1/orders(์ฌ์ฉ์ 1์ ์ฃผ๋ฌธ ๋ชฉ๋ก). - ๋ณต์ํ ์ฌ์ฉ:
/user/1(X) โ/users/1(O). ์ปฌ๋ ์ ๋จ์๋ก ์๊ฐํ๋ ๊ฒ์ด ๊ด๋ก์ ๋๋ค. - ๋ฒ์ ๊ด๋ฆฌ:
/v1/users. API ์คํ ๋ณ๊ฒฝ์ ๋๋นํ์ฌ ๊ฒฝ๋ก์ ๋ฒ์ ์ ํฌํจํฉ๋๋ค. - JSON ํ์ค ์ค์: ํญ์
Content-Type: application/json์ ์ ์งํฉ๋๋ค. - ๋ฉฑ๋ฑ์ฑ ํค(Idempotency Key): ๋คํธ์ํฌ ์ฅ์ ๋ก
POST์์ฒญ์ด ์ค๋ณต ์ ๋ฌ๋๋ ๊ฒ์ ๋ง๊ธฐ ์ํด, ํค๋์ ๊ณ ์ ํค๋ฅผ ๋ฃ์ด ์ค๋ณต ์์ฑ์ ๋ฐฉ์งํ๋ ๊ธฐ๋ฒ(Stripe ๋ฐฉ์)์ด ๋ง์ด ์ฐ์ ๋๋ค.
5. ๋ฐ์ดํฐ๊ฐ ์์ ๋์ ์ํ ์ฝ๋ ์ฒ๋ฆฌ (Q&A)
API ํธ์ถ์ ์ฑ๊ณตํ์ผ๋ ๋ฐ์ดํฐ๊ฐ ์๋ ๊ฒฝ์ฐ, ์ํฉ์ ๋ฐ๋ผ ์ ์ ํ ์ฝ๋๋ฅผ ์ ํํด์ผ ํฉ๋๋ค.
| ์์ฒญ ์ํฉ | ์ถ์ฒ ์ฝ๋ | ์๋ต ๋ณธ๋ฌธ(Body) | ๋น๊ณ |
|---|---|---|---|
| ๋ชฉ๋ก/๊ฒ์ ์กฐํ (๊ฒฐ๊ณผ 0๊ฑด) | 200 OK | [] (๋น ๋ฐฐ์ด) | "๊ฒ์ ๊ฒฐ๊ณผ๊ฐ ์์"๋ ํ๋์ ์ ํจํ ๊ฒฐ๊ณผ๋ก ๊ฐ์ฃผํฉ๋๋ค. |
| ํน์ ID ์กฐํ (๋ฐ์ดํฐ ์์) | 404 Not Found | ์๋ฌ ๋ฉ์์ง ๊ฐ์ฒด | ํด๋น URI์ ์์์ด ์กด์ฌํ์ง ์์์ ๋ช ์ํฉ๋๋ค. |
| ์ญ์ /์์ ์ฑ๊ณต (์๋ต ๋ฐ์ดํฐ ๋ถํ์) | 204 No Content | (์์) | ์ฑ๊ณต์ ํ์ผ๋ ์ ๋ฌํ ๋ณธ๋ฌธ์ด ์์ ๋ ์ฌ์ฉํฉ๋๋ค. |
- Tip:
204 No Content๋ฅผ ๊ฒ์ ๊ฒฐ๊ณผ๊ฐ ์์ ๋ ์ฌ์ฉํ๊ธฐ๋ ํ์ง๋ง, ํด๋ผ์ด์ธํธ ๊ฐ๋ฐ์๊ฐnull์ฒดํฌ๋ ๋น ๋ฐฐ์ด ์ฒดํฌ๋ฅผ ํ๋ ๊ฒ์ด ๋ ์ผ๋ฐ์ ์ด๋ฏ๋ก ๊ฒ์์200+[]๋ฅผ ๊ถ์ฅํฉ๋๋ค.
๊ฒฐ๋ก
์ข์ API๋ ์ค๋ช ์ ์์ด๋ ๊ทธ ํํ์ ์๋ต ์ฝ๋๋ง์ผ๋ก ๊ธฐ๋ฅ์ ์ง์ํ ์ ์๋ API์ ๋๋ค. ํ์ค์ ์ค์ํ๋ ๊ฒ์ด ๊ณง ์ต๊ณ ์ ๋ฌธ์ํ์ ๋๋ค.